﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using BO.Infrastructure.StaticData;
using BO.Infrastructure.Utils;
using BO.News;
using BO.Video;

namespace GUI.ProjectManager.Sitemap
{
    public partial class Generate : System.Web.UI.Page
    {
        private static DateTime START_TIME = new DateTime(2010, 1, 1, 0, 0, 0);
        private static DateTime VIDEO_START_TIME = new DateTime(2010, 1, 1, 0, 0, 0);
        private const string SITEMAP_FOLDER = "sitemaps";
        private const string XML_INDEX = "sitemap-index.xml";
        private const string XML_SETTING = "sitemap-setting.xml";
        private const string XSI = "http://www.w3.org/2001/XMLSchema-instance";
        private const string XMLNS = "http://www.sitemaps.org/schemas/sitemap/0.9";
        private const string XMLNS_VIDEO = "http://www.google.com/schemas/sitemap-video/1.1";
        private const string SITEMAP_SCHEMA_LOCATION = "http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd";
        private const string SITEMAP_INDEX_SCHEMA_LOCATION = "http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/siteindex.xsd";
        private string sitemapDomain = ConfigurationManager.AppSettings["SitemapDomain"];
        public string CategoryChangeFreq = "always";
        public string CategoryPiority = "0.8";
        private Regex regex = new Regex("(<[a-z0-9]+\\s*.*)namespace=\"[^\"]*\"(.*>)");



        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {

                UpdateSitemapForCategories();

                UpdateSitemapForTag();
                //return;
                //not firsttime
                if (LastGenerateTime != DateTime.MinValue)
                {
                    if (this.GenSitemap(LastGenerateTime, DateTime.Now))
                    {
                        this.ltrStatus.Text = "Updated successfull.";
                        LastGenerateTime = DateTime.Now;
                    }
                    else
                    {
                        this.ltrStatus.Text = "Server hasnt new data yet, no sitemap is updated";
                    }
                }
                else
                {

                    if (this.StartGenerate())
                    {
                        this.ltrStatus.Text = "Updated successfull.";
                        this.LastGenerateTime = DateTime.Now;
                    }
                    else
                    {
                        this.ltrStatus.Text = "Error";
                    }
                }


                if (LastVideoGenerateTime != DateTime.MinValue)
                {
                    if (this.GenSitemapVideo(LastVideoGenerateTime, DateTime.Now))
                    {
                        this.ltrVideoStatus.Text = "Updated successfull.";
                        LastVideoGenerateTime = DateTime.Now;
                    }
                    else
                    {
                        this.ltrVideoStatus.Text = "Server hasnt new data yet, no sitemap is updated";
                    }
                }
                else
                {
                    if (this.StartGenerateVideoSitemap())
                    {
                        this.ltrVideoStatus.Text = "Updated successfull.";
                        this.LastVideoGenerateTime = DateTime.Now;
                    }
                    else
                    {
                        this.ltrVideoStatus.Text = "Error";
                    }
                }

            }
        }

        private void UpdateSitemapForTag()
        {
            var dt = NewsBO_NoCache.GetAllTags();

            if (dt != null && dt.Rows.Count > 0)
            {
                var pageSize = 5000;
                int pageNum = (int)Math.Ceiling((decimal)dt.Rows.Count / pageSize);
                for (int i = 0; i < pageNum; i++)
                {
                    var dt1 = dt.Clone();
                    for (int j = i * pageSize; j < Math.Min((i + 1) * pageSize - 1, dt.Rows.Count); j++)
                    {
                        dt1.ImportRow(dt.Rows[j]);
                    }
                    UpdateSitemapForTag(string.Format("/sitemap-tag-{0}.xml", i), dt1);
                }

            }
        }

        private void UpdateSitemapForTag(string filePath, DataTable dt)
        {

            filePath = "/" + SITEMAP_FOLDER + filePath;// "/sitemap-tag.xml";
            var fullPath = Server.MapPath(filePath);
            XmlDocument doc = new XmlDocument();
            if (File.Exists(fullPath))
            {
                File.Delete(fullPath);
            }
            var urlSetElement = doc.CreateElement("urlset");
            urlSetElement.SetAttribute("xmlns:xsi", XSI);
            urlSetElement.SetAttribute("xmlns", XMLNS);

            XmlAttribute attr = doc.CreateAttribute("xsi", "schemaLocation", XSI);
            attr.Value = SITEMAP_SCHEMA_LOCATION;
            urlSetElement.Attributes.Append(attr);
            doc.AppendChild(urlSetElement);
            XmlDeclaration xmlDeclaration = doc.CreateXmlDeclaration("1.0", "utf-8", string.Empty);
            doc.InsertBefore(xmlDeclaration, doc.DocumentElement);
            doc.Save(fullPath);
            doc.Load(fullPath);



            {
                var urlSet = doc.GetElementsByTagName("urlset")[0];

                urlSet.InnerXml = string.Empty;
                //var dt = NewsBO_NoCache.GetAllTags();
                if (dt != null && dt.Rows.Count > 0)
                {
                    foreach (DataRow r in dt.Rows)
                    {
                        var urlElement = doc.CreateElement("url");

                        var locElement = doc.CreateElement("loc");
                        var tagId = PresentationUtils.Object2Integer(r[SqlConstants.Tag.Id].ToString());
                        var isThread = PresentationUtils.Object2Boolean(r[SqlConstants.Tag.IsThread].ToString());
                        var url = isThread
                            ? PresentationUtils.UrlBuilder.BuildThreadUrl(tagId, r[SqlConstants.Tag.Name].ToString())
                            : PresentationUtils.UrlBuilder.BuildTagUrl(r[SqlConstants.Tag.Name].ToString(), true);
                        locElement.InnerText = sitemapDomain + url;
                        urlElement.AppendChild(locElement);

                        var lastModElement = doc.CreateElement("lastmod");
                        lastModElement.InnerText = DateTime.Now.ToString("yyyy-MM-dd");
                        urlElement.AppendChild(lastModElement);

                        var changeFreqElement = doc.CreateElement("changefreq");
                        changeFreqElement.InnerText = this.CategoryChangeFreq;
                        urlElement.AppendChild(changeFreqElement);

                        var priorityElement = doc.CreateElement("priority");
                        priorityElement.InnerText = this.CategoryPiority;

                        //urlElement.InnerXml = urlElement.InnerXml.Replace("<url xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">", "<url>");
                        urlElement.AppendChild(priorityElement);


                        urlSet.AppendChild(urlElement);
                        urlSet.InnerXml = urlSet.InnerXml.Replace("<url xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">", "<url>");
                    }
                    doc.Save(fullPath);

                }
            }
            var indexSitemap = GetIndexSitemap();
            var itemlocation = sitemapDomain + filePath;
            var sitemapElementList = indexSitemap.GetElementsByTagName("sitemap");
            var flag = true;
            if (sitemapElementList != null)
            {
                foreach (XmlElement item in sitemapElementList)
                {
                    if (item["loc"].InnerText.Equals(itemlocation))
                    {
                        item["lastmod"].InnerText = DateTime.Now.ToString("yyyy-MM-dd");
                        flag = false;
                        break;
                    }
                }

            }
            if (flag)
            {

                var siteMapElement = indexSitemap.CreateElement(null, "sitemap", null);

                var locSitemapElement = indexSitemap.CreateElement("loc");

                locSitemapElement.InnerText = itemlocation;
                siteMapElement.AppendChild(locSitemapElement);

                var lastModSitemapElement = indexSitemap.CreateElement("lastmod");
                lastModSitemapElement.InnerText = DateTime.Now.ToString("yyyy-MM-dd");
                siteMapElement.AppendChild(lastModSitemapElement);

                var listSitemap = indexSitemap.GetElementsByTagName("sitemapindex")[0];
                if (listSitemap != null)
                {
                    listSitemap.InsertBefore(siteMapElement, listSitemap.FirstChild);
                    var regex = new Regex("(<[a-z0-9]+\\s*.*)namespace=\"[^\"]*\"(.*>)");
                    listSitemap.InnerXml = regex.Replace(listSitemap.InnerXml, "$1$2");
                }
            }
            indexSitemap.Save(this.GetIndexSitemapPath());
        }



        #region Video
        private bool StartGenerateVideoSitemap()
        {
            if (this.LastVideoGenerateTime == DateTime.MinValue)
            {
                for (int i = VIDEO_START_TIME.Year; i <= DateTime.Now.Year; i++)
                {
                    for (int j = 1; j <= 12; j++)
                    {
                        if (i == DateTime.Now.Year && j == DateTime.Now.Month)
                        {
                            if (DateTime.Now.Day > 1)
                            {
                                var startDate = new DateTime(i, j, 1, 0, 0, 0);
                                var endDate = DateTime.Now;
                                this.GenSitemapVideo(startDate, endDate);
                            }
                            break;
                        }
                        else
                        {
                            var startDate = new DateTime(i, j, 1, 0, 0, 0);
                            var endDate = new DateTime(i, j, DateTime.DaysInMonth(i, j), 23, 59, 59);
                            this.GenSitemapVideo(startDate, endDate);
                        }
                    }
                }
                return true;
            }
            return false;
        }


        private bool GenSitemapVideo(DateTime startDate, DateTime endDate)
        {
            var maxEndDate = new DateTime(startDate.Year, startDate.Month, DateTime.DaysInMonth(startDate.Year, startDate.Month), 23, 59, 59);
            if (endDate > maxEndDate)
            {
                GenSitemapVideo(maxEndDate.AddSeconds(1), endDate);
                endDate = maxEndDate;
            }

            //}
            string filePath = "/" + SITEMAP_FOLDER + "/sitemap-video-" + startDate.ToString("yyyy-MM") + ".xml";
            var fullPath = Server.MapPath(filePath);



            DataTable dt = VideoBO_NoCache.GetVideoByTime(startDate, endDate);
            if (dt != null && dt.Rows.Count > 0)
            {


                if (!dt.Columns.Contains("Title_P"))
                {
                    dt.Columns.Add("Title_P");
                }




                int count = dt.Rows.Count;

                //--- Chia phan cho cac video trung ten --//
                // Lay ra dictionary cac cap video trung nhau
                List<int> dupRow = new List<int>();
                Dictionary<string, List<int>> dctDupRows = new Dictionary<string, List<int>>();
                for (int i = 0; i < count; i++)
                {
                    dt.Rows[i]["Title_P"] = dt.Rows[i][SqlConstants.Video.Name];
                    for (int j = 0; j < count; j++)
                    {
                        if (i != j && dt.Rows[i][SqlConstants.Video.Name].ToString().Trim() == dt.Rows[j][SqlConstants.Video.Name].ToString().Trim())
                        {
                            if (!dctDupRows.ContainsKey(dt.Rows[i][SqlConstants.Video.Name].ToString().Trim()))
                            {

                                dctDupRows.Add(dt.Rows[i][SqlConstants.Video.Name].ToString().Trim(), new List<int>(new int[] { i, j }));
                            }
                            else
                            {
                                dupRow = dctDupRows[dt.Rows[i][SqlConstants.Video.Name].ToString().Trim()];
                                if (!dupRow.Contains(i)) { dupRow.Add(i); };
                                if (!dupRow.Contains(j)) { dupRow.Add(j); };
                                dctDupRows[dt.Rows[i][SqlConstants.Video.Name].ToString().Trim()] = dupRow;

                            }
                        }
                    }
                }
                // Them P
                foreach (KeyValuePair<string, List<int>> p in dctDupRows)
                {
                    for (int i = 0; i < p.Value.Count; i++)
                    {
                        var r = dt.Rows[p.Value[i]];
                        r["Title_P"] = string.Format("{0} (phần {1})", r[SqlConstants.Video.Name], i + 1);
                        r[SqlConstants.Video.Description] = string.Format("{0} (phần {1})", r[SqlConstants.Video.Description], i + 1);
                    }

                }


                dupRow = new List<int>();
                dctDupRows = new Dictionary<string, List<int>>();
                for (int i = 0; i < count; i++)
                {

                    for (int j = 0; j < count; j++)
                    {
                        if (i != j && dt.Rows[i][SqlConstants.Video.Description].ToString().Trim() == dt.Rows[j][SqlConstants.Video.Description].ToString().Trim())
                        {
                            if (!dctDupRows.ContainsKey(dt.Rows[i][SqlConstants.Video.Description].ToString().Trim()))
                            {

                                dctDupRows.Add(dt.Rows[i][SqlConstants.Video.Description].ToString().Trim(), new List<int>(new int[] { i, j }));
                            }
                            else
                            {
                                dupRow = dctDupRows[dt.Rows[i][SqlConstants.Video.Description].ToString().Trim()];
                                if (!dupRow.Contains(i)) { dupRow.Add(i); };
                                if (!dupRow.Contains(j)) { dupRow.Add(j); };
                                dctDupRows[dt.Rows[i][SqlConstants.Video.Description].ToString().Trim()] = dupRow;

                            }
                        }
                    }
                }
                foreach (KeyValuePair<string, List<int>> p in dctDupRows)
                {
                    for (int i = 0; i < p.Value.Count; i++)
                    {
                        var r = dt.Rows[p.Value[i]];
                        r[SqlConstants.Video.Description] = string.Format("{0}{1}", r[SqlConstants.Video.Description], BuildDot(i));
                    }

                }


                XmlDocument doc = new XmlDocument();
                if (!File.Exists(fullPath))
                {

                    var urlSetElement = doc.CreateElement("urlset");
                    urlSetElement.SetAttribute("xmlns", XMLNS);
                    urlSetElement.SetAttribute("xmlns:video", XMLNS_VIDEO);
                    doc.AppendChild(urlSetElement);

                    XmlDeclaration xmlDeclaration = doc.CreateXmlDeclaration("1.0", "utf-8", null);
                    doc.InsertBefore(xmlDeclaration, doc.DocumentElement);
                }
                else
                {
                    doc.Load(fullPath);
                }





                var urlSet = doc.GetElementsByTagName("urlset")[0];
                foreach (DataRow r in dt.Rows)
                {
                    var urlElement = doc.CreateElement("url");

                    var locElement = doc.CreateElement("loc");
                    locElement.InnerText = this.BuildVideoDetailsURL(r);
                    urlElement.AppendChild(locElement);


                    var videoElement = doc.CreateElement("video", "video", XMLNS_VIDEO);
                    //var s = doc.CreateElement("video", "video");

                    var thumbnailLoc = doc.CreateElement("video", "thumbnail_loc", XMLNS_VIDEO);
                    thumbnailLoc.InnerText = this.GetVideoThumbImage(r);
                    videoElement.AppendChild(thumbnailLoc);

                    var title = doc.CreateElement("video", "title", XMLNS_VIDEO);
                    title.InnerText = this.RemoveSpecialChars(r["Title_P"].ToString());
                    videoElement.AppendChild(title);

                    var desc = doc.CreateElement("video", "description", XMLNS_VIDEO);
                    desc.InnerText = this.RemoveSpecialChars(r[SqlConstants.Video.Description].ToString());
                    videoElement.AppendChild(desc);

                    var contentLoc = doc.CreateElement("video", "content_loc", XMLNS_VIDEO);
                    contentLoc.InnerText = this.BuildVideoContentLocation(r);
                    videoElement.AppendChild(contentLoc);


                    var rate = doc.CreateElement("video", "rating", XMLNS_VIDEO);
                    rate.InnerText = this.GetVideoRate(r);
                    videoElement.AppendChild(rate);

                    var publishDate = doc.CreateElement("video", "publication_date", XMLNS_VIDEO);
                    publishDate.InnerText = this.GetVideoPublishDate(r);
                    videoElement.AppendChild(publishDate);

                    var familyFriendly = doc.CreateElement("video", "family_friendly", XMLNS_VIDEO);
                    familyFriendly.InnerText = this.GetVideoFamilyFriendly(r);
                    videoElement.AppendChild(familyFriendly);

                    var tags = doc.CreateElement("video", "tag", XMLNS_VIDEO);
                    tags.InnerText = this.GetVideoRelationTags(r);
                    videoElement.AppendChild(tags);

                    var category = doc.CreateElement("video", "category", XMLNS_VIDEO);
                    category.InnerText = this.GetVideoCategory(r);
                    videoElement.AppendChild(category);

                    var uploader = doc.CreateElement("video", "uploader", XMLNS_VIDEO);
                    uploader.SetAttribute("info", sitemapDomain);
                    uploader.InnerText = sitemapDomain;
                    videoElement.AppendChild(uploader);

                    var live = doc.CreateElement("video", "live", XMLNS_VIDEO);
                    live.InnerText = this.GetVideoLiveStatus(r);
                    videoElement.AppendChild(live);


                    urlElement.AppendChild(videoElement);

                    urlSet.InsertBefore(urlElement, urlSet.FirstChild);
                }


                doc.Save(fullPath);

                //save vao file sitemap-index
                var indexSitemap = this.GetIndexSitemap();
                var itemlocation = sitemapDomain + filePath;
                if (File.Exists(fullPath))
                {
                    var sitemapElementList = indexSitemap.GetElementsByTagName("sitemap");
                    var flag = true;
                    if (sitemapElementList != null)
                    {
                        foreach (XmlElement item in sitemapElementList)
                        {
                            if (item["loc"].InnerText.Equals(itemlocation))
                            {
                                item["lastmod"].InnerText = DateTime.Now.ToString("yyyy-MM-dd");
                                flag = false;
                                break;
                            }
                        }

                    }
                    if (flag)
                    {

                        var siteMapElement = indexSitemap.CreateElement("sitemap", null);

                        var locSitemapElement = indexSitemap.CreateElement("loc");

                        locSitemapElement.InnerText = itemlocation;
                        siteMapElement.AppendChild(locSitemapElement);

                        var lastModSitemapElement = indexSitemap.CreateElement("lastmod");
                        lastModSitemapElement.InnerText = DateTime.Now.ToString("yyyy-MM-dd");
                        siteMapElement.AppendChild(lastModSitemapElement);
                        var listSitemap = indexSitemap.GetElementsByTagName("sitemapindex")[0];
                        if (listSitemap != null)
                        {
                            listSitemap.InsertBefore(siteMapElement, listSitemap.FirstChild);
                            var regex = new Regex("(<[a-z0-9]+\\s*.*)namespace=\"[^\"]*\"(.*>)");
                            listSitemap.InnerXml = regex.Replace(listSitemap.InnerXml, "$1$2");
                        }
                    }
                    indexSitemap.Save(this.GetIndexSitemapPath());
                    return true;
                }
            }

            return false;
        }

        private string RemoveSpecialChars(string p)
        {
            return p;
        }

        private string BuildDot(int c)
        {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < c; i++)
            {
                sb.Append(".");
            }
            return sb.ToString();

        }



        private string GetVideoLiveStatus(DataRow r)
        {
            return "no";
        }

        private string GetVideoCategoryDetailsURL(DataRow r)
        {
            return string.Empty;
        }

        private string GetVideoCategory(DataRow r)
        {
            return r[SqlConstants.ZoneVideo.Name].ToString();
        }

        private string GetVideoRelationTags(DataRow r)
        {
            //var videoID = Lib.Object2Integer(r[Const.Video.ID].ToString());
            //DataTable dtTags = VideoBO.GetVideoTags(videoID);
            //if (dtTags != null && dtTags.Rows.Count > 0)
            //{
            //    StringBuilder sb = new StringBuilder();
            //    for (int i = 0; i < dtTags.Rows.Count; i++)
            //    {
            //        DataRow row = dtTags.Rows[i];
            //        sb.Append(r[Const.ZoneVideo.Name].ToString());
            //        sb.Append(",");
            //        sb.Append(r[Const.ZoneVideo.Url].ToString());
            //        if (i < dtTags.Rows.Count - 1)
            //        {
            //            sb.Append(",");
            //        }
            //    }
            //    return sb.ToString();
            //}
            return string.Empty;
        }

        private string GetVideoFamilyFriendly(DataRow r)
        {
            return "yes";
        }

        private string GetVideoPublishDate(DataRow r)
        {
            return PresentationUtils.Object2DateTime(r[SqlConstants.Video.PublishDate].ToString()).ToString("yyyy-MM-dd");
        }

        private string GetVideoRate(DataRow r)
        {
            return "5";
        }

        private string BuildVideoContentLocation(DataRow r)
        {
            return string.Format(
                    "{0}?key={1}",
                    HostVideo,
                    r[SqlConstants.Video.KeyVideo].ToString()
                );
        }

        private string GetVideoThumbImage(DataRow r)
        {
            return PresentationUtils.Photo.GetVideoAvatarSource(r[SqlConstants.Video.Avatar].ToString());

        }

        private string BuildVideoDetailsURL(DataRow r)
        {

            return sitemapDomain + PresentationUtils.UrlBuilder.BuildVideoUrl(r[SqlConstants.Video.Name], r[SqlConstants.Video.Id]);
        }


        public DateTime LastVideoGenerateTime
        {
            get
            {
                var docSetting = GetSitemapSetting();
                if (docSetting.GetElementsByTagName("lasttime-video").Count == 0)
                {
                    var lastVideoGenerateElement = docSetting.CreateElement("lasttime-video");
                    docSetting.DocumentElement.AppendChild(lastVideoGenerateElement);
                    docSetting.Save(this.GetSitemapSettingPath());
                    return DateTime.MinValue;
                }
                var lasttimeElement = docSetting.GetElementsByTagName("lasttime-video")[0];
                if (lasttimeElement == null || string.IsNullOrEmpty(lasttimeElement.InnerText))
                {
                    return DateTime.MinValue;
                }
                return PresentationUtils.Object2DateTime(lasttimeElement.InnerText);
            }
            private set
            {
                var docSetting = GetSitemapSetting();
                var lasttimeElement = docSetting.GetElementsByTagName("lasttime-video")[0];
                if (lasttimeElement != null)
                {
                    lasttimeElement.InnerText = value.ToString();
                    docSetting.Save(GetSitemapSettingPath());
                }

            }
        }

        #endregion

        #region News
        private void UpdateSitemapForCategories()
        {

            string filePath = "/" + SITEMAP_FOLDER + "/sitemap-category.xml";
            var fullPath = Server.MapPath(filePath);
            XmlDocument doc = new XmlDocument();
            //var isMofidy = false;
            if (File.Exists(fullPath))
            {
                File.Delete(fullPath);
            }

            var urlSetElement = doc.CreateElement("urlset");
            urlSetElement.SetAttribute("xmlns:xsi", XSI);
            urlSetElement.SetAttribute("xmlns", XMLNS);

            XmlAttribute attr = doc.CreateAttribute("xsi", "schemaLocation", XSI);
            attr.Value = SITEMAP_SCHEMA_LOCATION;
            urlSetElement.Attributes.Append(attr);
            doc.AppendChild(urlSetElement);
            XmlDeclaration xmlDeclaration = doc.CreateXmlDeclaration("1.0", "utf-8", string.Empty);
            doc.InsertBefore(xmlDeclaration, doc.DocumentElement);
            doc.Save(fullPath);
            //}
            //else
            //{
            //isMofidy = true;
            doc.Load(fullPath);
            //}


            {
                var urlSet = doc.GetElementsByTagName("urlset")[0];

                urlSet.InnerXml = string.Empty;
                var categories = NewsBO_NoCache.GetInstance().GetAllCategories();
                if (categories != null && categories.Count > 0)
                {
                    foreach (var c in categories)
                    {
                        var urlElement = doc.CreateElement("url");

                        var locElement = doc.CreateElement("loc");
                        locElement.InnerText = sitemapDomain + c.Url;
                        urlElement.AppendChild(locElement);

                        var lastModElement = doc.CreateElement("lastmod");
                        lastModElement.InnerText = DateTime.Now.ToString("yyyy-MM-dd");
                        urlElement.AppendChild(lastModElement);

                        var changeFreqElement = doc.CreateElement("changefreq");
                        changeFreqElement.InnerText = this.CategoryChangeFreq;
                        urlElement.AppendChild(changeFreqElement);

                        var priorityElement = doc.CreateElement("priority");
                        priorityElement.InnerText = this.CategoryPiority;
                        urlElement.AppendChild(priorityElement);


                        urlSet.AppendChild(urlElement);
                    }
                    urlSet.InnerXml = regex.Replace(urlSet.InnerXml, "$1$2");
                    doc.Save(fullPath);

                }
            }
            var indexSitemap = GetIndexSitemap();
            var itemlocation = sitemapDomain + filePath;
            var sitemapElementList = indexSitemap.GetElementsByTagName("sitemap");
            var flag = true;
            if (sitemapElementList != null)
            {
                foreach (XmlElement item in sitemapElementList)
                {
                    if (item["loc"].InnerText.Equals(itemlocation))
                    {
                        item["lastmod"].InnerText = DateTime.Now.ToString("yyyy-MM-dd");
                        flag = false;
                        break;
                    }
                }

            }
            if (flag)
            {

                var siteMapElement = indexSitemap.CreateElement(null, "sitemap", null);

                var locSitemapElement = indexSitemap.CreateElement("loc");

                locSitemapElement.InnerText = itemlocation;
                siteMapElement.AppendChild(locSitemapElement);

                var lastModSitemapElement = indexSitemap.CreateElement("lastmod");
                lastModSitemapElement.InnerText = DateTime.Now.ToString("yyyy-MM-dd");
                siteMapElement.AppendChild(lastModSitemapElement);

                var listSitemap = indexSitemap.GetElementsByTagName("sitemapindex")[0];
                if (listSitemap != null)
                {
                    listSitemap.InsertBefore(siteMapElement, listSitemap.FirstChild);
                    var regex = new Regex("(<[a-z0-9]+\\s*.*)namespace=\"[^\"]*\"(.*>)");
                    listSitemap.InnerXml = regex.Replace(listSitemap.InnerXml, "$1$2");
                }
            }
            indexSitemap.Save(this.GetIndexSitemapPath());
        }

        private bool GenSitemap(DateTime startDate, DateTime endDate)
        {

            var maxEndDate = new DateTime(startDate.Year, startDate.Month, DateTime.DaysInMonth(startDate.Year, startDate.Month), 23, 59, 59);
            if (endDate > maxEndDate)
            {
                GenSitemap(maxEndDate.AddSeconds(1), endDate);
                endDate = maxEndDate;
            }

            string filePath = "/" + SITEMAP_FOLDER + "/sitemap-" + startDate.ToString("yyyy-MM") + ".xml";
            var fullPath = Server.MapPath(filePath);



            DataTable dt = NewsBO_NoCache.GetNewsByTime(startDate, endDate);
            if (dt != null && dt.Rows.Count > 0)
            {
                //gen theo thang'
                var isModify = false;
                XmlDocument doc = new XmlDocument();
                if (!File.Exists(fullPath))
                {

                    var urlSetElement = doc.CreateElement("urlset");
                    urlSetElement.SetAttribute("xmlns:xsi", XSI);
                    urlSetElement.SetAttribute("xmlns", XMLNS);

                    XmlAttribute attr = doc.CreateAttribute("xsi", "schemaLocation", XSI);
                    attr.Value = SITEMAP_SCHEMA_LOCATION;
                    urlSetElement.Attributes.Append(attr);
                    doc.AppendChild(urlSetElement);
                    XmlDeclaration xmlDeclaration = doc.CreateXmlDeclaration("1.0", "utf-8", string.Empty);
                    doc.InsertBefore(xmlDeclaration, doc.DocumentElement);
                }
                else
                {
                    isModify = true;
                    doc.Load(fullPath);
                }



                {
                    var urlSet = doc.GetElementsByTagName("urlset")[0];
                    foreach (DataRow r in dt.Rows)
                    {
                        if (!r[SqlConstants.NewsPublish.Url].ToString().StartsWith("/yeu/"))
                        {
                            var urlElement = doc.CreateElement("url");

                            var locElement = doc.CreateElement("loc");
                            locElement.InnerText = sitemapDomain + r[SqlConstants.NewsPublish.Url].ToString();
                            urlElement.AppendChild(locElement);

                            var lastModElement = doc.CreateElement("lastmod");
                            lastModElement.InnerText = this.GetNewsLastModify(r);
                            urlElement.AppendChild(lastModElement);

                            var changeFreqElement = doc.CreateElement("changefreq");
                            changeFreqElement.InnerText = this.GetNewsChangeFreq();
                            urlElement.AppendChild(changeFreqElement);

                            var priorityElement = doc.CreateElement("priority");
                            priorityElement.InnerText = this.GetNewsPiority();
                            urlElement.AppendChild(priorityElement);


                            urlSet.InsertBefore(urlElement, urlSet.FirstChild);
                        }

                    }

                    if (isModify) urlSet.InnerXml = urlSet.InnerXml.Replace(" xmlns=\"\"", string.Empty);
                    doc.Save(fullPath);
                }
                //save vao file sitemap-index
                var indexSitemap = this.GetIndexSitemap();
                var itemlocation = sitemapDomain.TrimEnd('/') + filePath;
                if (File.Exists(fullPath))
                {
                    var sitemapElementList = indexSitemap.GetElementsByTagName("sitemap");
                    var flag = true;
                    if (sitemapElementList != null)
                    {
                        foreach (XmlElement item in sitemapElementList)
                        {
                            if (item["loc"].InnerText.Equals(itemlocation))
                            {
                                item["lastmod"].InnerText = DateTime.Now.ToString("yyyy-MM-dd");
                                flag = false;
                                break;
                            }
                        }

                    }
                    if (flag)
                    {

                        var siteMapElement = indexSitemap.CreateElement(null, "sitemap", null);

                        var locSitemapElement = indexSitemap.CreateElement("loc");

                        locSitemapElement.InnerText = itemlocation;
                        siteMapElement.AppendChild(locSitemapElement);

                        var lastModSitemapElement = indexSitemap.CreateElement("lastmod");
                        lastModSitemapElement.InnerText = DateTime.Now.ToString("yyyy-MM-dd");
                        siteMapElement.AppendChild(lastModSitemapElement);

                        var listSitemap = indexSitemap.GetElementsByTagName("sitemapindex")[0];
                        if (listSitemap != null)
                        {

                            listSitemap.InsertBefore(siteMapElement, listSitemap.FirstChild);
                            var regex = new Regex("(<[a-z0-9]+\\s*.*)namespace=\"[^\"]*\"(.*>)");
                            listSitemap.InnerXml = regex.Replace(listSitemap.InnerXml, "$1$2");
                        }
                    }
                    indexSitemap.Save(this.GetIndexSitemapPath());
                    return true;
                }
            }

            return false;
        }

        private string GetNewsPiority()
        {
            return "0.6";
        }

        private string GetNewsChangeFreq()
        {
            return "daily";
        }

        private string GetNewsLastModify(DataRow r)
        {
            return DateTime.Now.ToString("yyyy-MM-dd");
        }

        private string GetIndexSitemapPath()
        {
            return Server.MapPath("/" + SITEMAP_FOLDER + "/" + XML_INDEX);
        }

        private bool StartGenerate()
        {
            //firsttime

            if (LastGenerateTime == DateTime.MinValue)
            {
                for (int i = START_TIME.Year; i <= DateTime.Now.Year; i++)
                {
                    for (int j = 1; j <= 12; j++)
                    {
                        if (i == DateTime.Now.Year && j == DateTime.Now.Month)
                        {
                            if (DateTime.Now.Day > 1)
                            {
                                var startDate = new DateTime(i, j, 1, 0, 0, 0);
                                var endDate = DateTime.Now;
                                this.GenSitemap(startDate, endDate);
                            }
                            break;
                        }
                        else
                        {
                            var startDate = new DateTime(i, j, 1, 0, 0, 0);
                            var endDate = new DateTime(i, j, DateTime.DaysInMonth(i, j), 23, 59, 59);
                            this.GenSitemap(startDate, endDate);
                        }
                    }
                }

                return true;
            }


            return false;
        }

        public DateTime LastGenerateTime
        {
            get
            {
                var docSetting = GetSitemapSetting();
                if (docSetting.GetElementsByTagName("lasttime").Count == 0)
                {
                    var lastVideoGenerateElement = docSetting.CreateElement("lasttime");
                    docSetting.DocumentElement.AppendChild(lastVideoGenerateElement);
                    docSetting.Save(this.GetSitemapSettingPath());
                    return DateTime.MinValue;
                }
                var lasttimeElement = docSetting.GetElementsByTagName("lasttime")[0];
                if (lasttimeElement == null || string.IsNullOrEmpty(lasttimeElement.InnerText))
                {
                    return DateTime.MinValue;
                }
                return PresentationUtils.Object2DateTime(lasttimeElement.InnerText);
            }
            private set
            {
                var docSetting = GetSitemapSetting();
                var lasttimeElement = docSetting.GetElementsByTagName("lasttime")[0];
                if (lasttimeElement != null)
                {
                    lasttimeElement.InnerText = value.ToString();
                    docSetting.Save(GetSitemapSettingPath());
                }

            }
        }
        #endregion


        #region General
        private string GetSitemapSettingPath()
        {
            return Server.MapPath("/" + SITEMAP_FOLDER + "/" + XML_SETTING);
        }

        private XmlDocument GetIndexSitemap()
        {
            var indexSitemapPath = this.GetIndexSitemapPath();
            XmlDocument doc = new XmlDocument();
            if (!File.Exists(indexSitemapPath))
            {
                return this.CreateSitemapIndex();
            }
            doc.Load(indexSitemapPath);
            return doc;

        }

        private XmlDocument CreateSitemapIndex()
        {
            XmlDocument doc = new XmlDocument();
            var sitemapIndexElement = doc.CreateElement("sitemapindex");
            sitemapIndexElement.SetAttribute("xmlns:xsi", XSI);
            sitemapIndexElement.SetAttribute("xmlns", XMLNS);

            XmlAttribute attr = doc.CreateAttribute("xsi", "schemaLocation", XSI);
            attr.Value = SITEMAP_INDEX_SCHEMA_LOCATION;
            sitemapIndexElement.Attributes.Append(attr);


            doc.AppendChild(sitemapIndexElement);
            XmlDeclaration xmlDeclaration = doc.CreateXmlDeclaration("1.0", "utf-8", string.Empty);
            doc.InsertBefore(xmlDeclaration, doc.DocumentElement);
            doc.Save(this.GetIndexSitemapPath());
            return doc;
        }

        private XmlDocument GetSitemapSetting()
        {
            XmlDocument doc = new XmlDocument();
            var sitemapSettingPath = this.GetSitemapSettingPath();
            if (!File.Exists(sitemapSettingPath))
            {
                return CreateSitemapSetting();
            }
            doc.Load(sitemapSettingPath);
            return doc;
        }

        private XmlDocument CreateSitemapSetting()
        {

            XmlDocument doc = new XmlDocument();
            doc.AppendChild(doc.CreateElement("settings"));
            var lastGenerateElement = doc.CreateElement("lasttime");
            doc.DocumentElement.AppendChild(lastGenerateElement);
            var lastVideoGenerateElement = doc.CreateElement("lasttime-video");
            doc.DocumentElement.AppendChild(lastVideoGenerateElement);
            doc.Save(this.GetSitemapSettingPath());
            return doc;
        }
        #endregion




        public string HostVideo = "http://cache.hosting.vcmedia.vn";



    }
}